<?
//Designer 0.2.7
class design{
    private $symbiont;      //Symbiont name
    private $design;        //Design file name
    private $template;      //Template file name
    private $intro;         //Intro file name
    private $start;         //Start symbols
    private $end;           //End symbols
    private $content;       //Current content
    private $intro_content; //Intro content
    private $globals;       //Global vars
    private $intro_globals; //Inro global vars
    private $builded;       //
    
    function __construct($design="index", $symbiont="", $include=true, $temp=""){
        global $kernel;
        //Generation vars
        $this->symbiont=$symbiont;
        if($design!=""){
            $this->design="./design/".$kernel->site->get('design')."/".$design.".des.html";
            $this->template="./temp/".$kernel->site->get('design')."/".$design.".tpl.php";
            $this->intro="./temp/".$kernel->site->get('design')."/".$design.".tpi.php";
            $this->builded=file_exists($this->template);
        }
        else{
            $this->design=$this->template=$this->intro="";
        }
        $this->start='<?=';
        $this->start_w='<?';
        $this->end='?>';
        $this->globals=new set();
	$this->intro_globals=new set();
        //Creating necessary folders
        if($s=substr_count($design, "/")){
            $dir="./temp/";
            $this->create_dir($dir);
            $dir.=$kernel->site->get('design')."/";
            $this->create_dir($dir);
            $tok=strtok($design, "/");
            for($i=0; $i<$s; $i++){
                $dir.=$tok."/";
                $d=is_dir($dir);
                if(!$d){
                    mkdir($dir);
                }
                $tok=strtok("/");
            }
        }
        //Generating templates
        if($temp){
            $this->content=$temp;
            $this->build(0);
	    if($include) $this->inc();
        }
        elseif($this->design!=""){
            if(!file_exists($this->design)&&!file_exists($this->template)) $m=new message("Нет файла дизайна.");
            elseif(!file_exists($this->template)&&file_exists($this->design)){
                $this->build();
                include($this->intro);
            }
            else{
                include($this->intro);
            }
            $kernel->inc();
            if($include) $this->inc();
        }
        else{
            $this->build();
        }
	//Remove temp folder
	if($kernel->site->temp_regenerate=="true"&&$design=='pages/'.$kernel->page->template){
		data::folder_delete("temp/".$kernel->site->design);
	}
    }
    //Create folder
    private function create_dir($dir){
        if(!is_dir($dir)){
            mkdir($dir);
        }
    }
    //Template generating
    function build($type=1, $ceml=1){
        if($type==1) $this->content=file_get_contents($this->design);
        if($ceml==1) $this->ceml();
        $this->add_globals();
        if($this->design!=""){
            $file=fopen($this->template, "w");
            fwrite($file, $this->content);
            $file=fopen($this->intro, "w");
            fwrite($file, "<?\n".$this->intro_content."\n?>");
        }
    }
    //Processing CEML
    function ceml($elements="", $text="", $start="", $end=""){
        if(is_array($elements)){
            $elements=new multitude($elements);
        }
        if(!$elements||$elements->exists("symbionts_container")) $this->symbionts_container($text, $start, $end);
        if(!$elements||$elements->exists("ifs")) $this->ifs($text, $start, $end);
        if(!$elements||$elements->exists("local_vars_init")) $this->local_vars_init($text, $start, $end);
        if(!$elements||$elements->exists("dinamic_positions")) $this->dinamic_positions($text, $start, $end);
        if(!$elements||$elements->exists("vars")) $this->vars($text, $start, $end);
        if(!$elements||$elements->exists("static_vars")) $this->static_vars($text, $start, $end);
        if(!$elements||$elements->exists("symbionts")) $this->symbionts($text, $start, $end);
        if(!$elements||$elements->exists("symbionts_template")) $this->symbionts_template($text, $start, $end);
        if(!$elements||$elements->exists("positions")) $this->positions($text, $start, $end);
        if(!$elements||$elements->exists("local_vars")) $this->local_vars($text, $start, $end);
        if(!$elements||$elements->exists("labels")) $this->labels($text, $start, $end);
    }
    //Delete template
    function delete(){
        if(file_exists($this->template)){
            unlink($this->template);
        }
    }
    //Processing vars
    function vars($text="", $start="", $end=""){
        $temp=$text==""?$this->content:$text;
        if($start=="") $start=$this
	->start;
        if($end=="") $end=$this->end;
        preg_match_all("/\{\\\$([a-zA-Z0-9_]*)\}/", $temp, $matches);
        $i=0;
        foreach($matches[0] as $old){
            $var=$matches[1][$i];
            $new=$start."\$kernel->vars->".$var.$end;
            $temp=str_replace($old, $new, $temp);
            ++$i;
        }
        if($i!=0) $this->globals->push('kernel');
        if($text==""){
            $this->content=$temp;
        }
        else{
            return $temp;
        }
    }
    //Processing static vars
    function static_vars($text=""){
        global $kernel;
        $temp=$text==""?$this->content:$text;
        preg_match_all("/\{#([a-zA-Z0-9_]*)\}/", $temp, $matches);
        $i=0;
        foreach($matches[0] as $old){
            $var=$matches[1][$i];
            $new=$kernel->vars->get($var);
            $temp=str_replace($old, $new, $temp);
            ++$i;
        }
        if($text==""){
            $this->content=$temp;
        }
        else{
            return $temp;
        }
    }
    //Processing labels
    function labels($text="", $start_w="", $end=""){
        $temp=$text==""?$this->content:$text;
        if($start_w=="") $start_w=$this->start_w;
        if($end=="") $end=$this->end;
        preg_match_all("/\{@([a-zA-Z0-9_\.]*)(\|([a-zA-Z0-9]*))?\}/", $temp, $matches);
        $i=0;
        foreach($matches[0] as $old){
            $word=$matches[1][$i];
            $label=new label($word);
            if($label->id){
		if($matches[3][$i]){
		    switch($matches[3][$i]){
			case 'lower': $function='strtolower'; break;
			case 'upper': $function='strtoupper'; break;
			case 'first': $function='ucfirst'; break;
			case 'word': $function='ucwords'; break;
			default: $function=''; break;
		    }
		    $new="\$l=new label(".$label->id."); print(".$function."(\$l->get()));";
		}
		else{
		    $new="\$l=new label(".$label->id."); print(\$l->get());";
		}
                $new=$start_w.$new.$end;
            }
            else{
                $new='@'.$word;
            }
            $temp=str_replace($old, $new, $temp);
            ++$i;
        }
        if($text==""){
            $this->content=$temp;
        }
        else{
            return $temp;
        }
    }
    //Processing symbionts
    function symbionts($text="", $start="", $end=""){
        global $kernel;
        $temp=$text==""?$this->content:$text;
        if($start=="") $start=$this->start;
        if($end=="") $end=$this->end;
        preg_match_all("/\{([a-zA-Z0-9_\.-]*)\}/", $temp, $matches);
        $i=0;
        foreach($matches[0] as $old){
            $word=$matches[1][$i];
            list($new, $head)=self::symbiont($word);
            $new=$start.$new.$end;
            $temp=str_replace($old, $new, $temp);
            $this->intro_content.=$head;
            ++$i;
        }
        if($i!=0) $this->globals->push('sym');
        if($text==""){
            $this->content=$temp;
        }
        else{
            return $temp;
        }
    }
    //Processing symbiont standart view
    static function symbiont($word, $template=""){
        $words=explode(".", $word);
        if(substr_count($words[0], "-")){
            list($symbiont, $class)=explode("-", $words[0]);
        }
        else{
            $symbiont=$class=$words[0];
        }
        $func=isset($words[1])&&$words[1]?"___".$words[1]:"___main";
        $sc=$symbiont!=$class?$symbiont."_".$class:$symbiont;
        $sym="isset(\$sym->".$sc.")?\$sym->".$sc."->".$func."(\"".$template."\"";
        for($i=2; isset($words[$i]); ++$i){
            $sym.=", ";
            if(data::is_int($words[$i])||data::is_bool($words[$i])) $sym.=$words[$i];
            else $sym.="\"".$words[$i]."\"";
        }
        $sym.="):''";
        $inc="\$kernel->symbionts->push(\"".$words[0]."\");";
        return array($sym, $inc);
    }
    static function symbiont_explode($word){
	$ret=array('full'=>$word);
	if($p=strpos($word, '|')){
	    $ret['template']=substr($word, $p+1);
	    $word=substr($word, 0, $p);
	}
	$words=explode(".", $word);
        if(substr_count($words[0], "-")){
            list($ret['symbiont'], $ret['class'])=explode("-", $words[0]);
        }
        else{
            $ret['symbiont']=$ret['class']=$words[0];
        }
	if(isset($words[1])&&$words[1]){
	    $ret['function']=$words[1];
	}
	else{
	    $ret['function']='main';
	    if(isset($words[2])) $ret['full'].='.main';
	}
        for($i=2; isset($words[$i]); ++$i){
            $ret[]=$words[$i];
	    if($i==2) $ret['addition']=$words[$i];
	    else $ret['addition'].='.'.$words[$i];
        }
	if(!isset($ret['addition'])) $ret['addition']='';
        return $ret;
    }
    //Processing symbionts with templates
    function symbionts_template($text="", $start="", $end=""){
        global $kernel;
        $temp=$text==""?$this->content:$text;
        if($start=="") $start=$this->start;
        if($end=="") $end=$this->end;
        preg_match_all("/\{([a-zA-Z0-9_\.-]*)\|([a-zA-Z0-9_\/]*)\}/", $temp, $matches);
        $i=0;
        foreach($matches[0] as $old){
            $word=$matches[1][$i];
            $template=$matches[2][$i];
            list($new, $head)=self::symbiont($word, $template);
            $new=$start.$new.$end;
            $temp=str_replace($old, $new, $temp);
            $this->intro_content.=$head;
            ++$i;
        }
        if($i!=0) $this->globals('sym');
        if($text==""){
            $this->content=$temp;
        }
        else{
            return $temp;
        }
    }
    //Processing container symbionts
    function symbionts_container($text="", $start="", $end=""){
        global $kernel;
        $temp=$text==""?$this->content:$text;
        if($start=="") $start=$this->start;
        if($end=="") $end=$this->end;
        preg_match_all("/{%([a-zA-Z0-9_-]*)([a-zA-Z0-9\._]*)}(.*){\/\\1}/Us", $temp, $matches);
        $i=0;
        foreach($matches[0] as $old){
            $word=$matches[1][$i].$matches[2][$i];
            $tpl=$matches[3][$i];
            $template="contain/".data::rand(6);
            $e=explode("-", $matches[1][$i]);
            if(count($e)==2) $class=$e[0]!=$e[1]?$e[0]."_".$e[1]:$e[0];
            else $class=$e[0];
            $d=new design($template, $class, false, $tpl);
            list($new, $head)=self::symbiont($word, $template);
            $new=$start.$new.$end;
            $temp=str_replace($old, $new, $temp);
            $this->intro_content.=$head;
            ++$i;
        }
        if($i!=0) $this->globals->push('sym');
        if($text==""){
            $this->content=$temp;
        }
        else{
            return $temp;
        }
    }
    //Processing positions
    function positions($text=""){
        global $kernel;
        $temp=$text==""?$this->content:$text;
        preg_match_all("/{\[([a-zA-Z0-9_.]*)\]}/", $temp, $matches);
        $i=0;
        foreach($matches[0] as $old){
            $name=$matches[1][$i];
            $p=new positions("", $name);
	    global $sql;
            $id=$p->id;
            if($id){
                $new="\$p=new positions($id); \$p->prints();";
                $new=$this->start_w.$new.$this->end;
            }
            else{
                $new="";
            }
            $temp=str_replace($old, $new, $temp);
            ++$i;
        }
        if($text==""){
            $this->content=$temp;
        }
        else{
            return $temp;
        }
    }
    //Processing dinamic positions
    function dinamic_positions($text=""){
        global $kernel;
        $temp=$text==""?$this->content:$text;
        preg_match_all("/\{([a-zA-Z0-9_]*)\{([a-zA-Z0-9_]*)\}([a-zA-Z0-9_]*)\}/", $temp, $matches);
        $i=0;
        foreach($matches[0] as $old){
            $prefix=$matches[1][$i];
            $name=$matches[2][$i];
            $suffix=$matches[3][$i];
            $new="\$p=new positions('', \"".$prefix."\".\$kernel->vars->".$name.".\"".$suffix."\"); \$p->prints();";
            $new=$this->start_w.$new.$this->end;
            $temp=str_replace($old, $new, $temp);
            ++$i;
        }
        if($text==""){
            $this->content=$temp;
        }
        else{
            return $temp;
        }
    }
    //Processing ifs
    function ifs($text=""){
        $temp=$text==""?$this->content:$text;
        //if
        preg_match_all("/\{if\(([a-zA-Z0-9_~\}\{\-. ><=!\&\#\$\'\"\|]*)\)\}/", $temp, $matches);
        $i=0;
        foreach($matches[0] as $old){
            $ext=$matches[1][$i];
            if(substr_count($ext, "~")) $this->globals->push('user');
            $ext=$this->vars($ext, " ", " ");
            $ext=$this->local_vars($ext, " ", " ");
            $ext=$this->symbionts($ext, " ", " ");
            $ext=str_replace("~", "\$user->access_level", $ext);
            $new="<?if(".$ext."){?>";
            $temp=str_replace($old, $new, $temp);
            ++$i;
        }
        //elseif
        preg_match_all("/\{elseif\(([a-zA-Z0-9_~\}\{\-. ><=!\&\#\$\'\"]*)\)\}/", $temp, $matches);
        $i=0;
        foreach($matches[0] as $old){
            $ext=$matches[1][$i];
            if(substr_count($ext, "~")) $this->globals->push('user');
            $ext=$this->vars($ext, " ", " ");
            $ext=$this->local_vars($ext, " ", " ");
            $ext=$this->symbionts($ext, " ", " ");
            $ext=str_replace("~", "\$user->get(\"access_level\")", $ext);
            $new="<?}elseif(".$ext."){?>";
            $temp=str_replace($old, $new, $temp);
            ++$i;
        }
        //else
        preg_match_all("/\{else\}/", $temp, $matches);
        $i=0;
        foreach($matches[0] as $old){
            $new="<?}else{?>";
            $temp=str_replace($old, $new, $temp);
            ++$i;
        }
        ///if
        preg_match_all("/\{\/if\}/", $temp, $matches);
        $i=0;
        foreach($matches[0] as $old){
            $new="<?}?>";
            $temp=str_replace($old, $new, $temp);
            ++$i;
        }
        if($text==""){
            $this->content=$temp;
        }
        else{
            return $temp;
        }
    }
    //Processing local vars
    function local_vars($text="", $start="", $end=""){
        $temp=$text==""?$this->content:$text;
        if($start=="") $start=$this->start;
        if($end=="") $end=$this->end;
        preg_match_all("/{\&([a-zA-Z0-9_]*)(\[([a-zA-Z0-9_]*)\])*}/", $temp, $matches);
        $i=0;
        foreach($matches[0] as $old){
            $var=$matches[1][$i];
			if($matches[3][$i]!==FALSE && $matches[3][$i]!='')
				$var .= is_numeric($matches[3][$i])?'['.$matches[3][$i].']':'["'.$matches[3][$i].'"]';
            $new='$sym->'.$this->symbiont.'->'.$var;
            $new=$start.$new.$end;
            $temp=str_replace($old, $new, $temp);
            ++$i;
        }
        if($i!=0) $this->globals->push('sym');
        if($text==""){
            $this->content=$temp;
        }
        else{
            return $temp;
        }
    }
    //Inicialisate local vars
    function local_vars_init($text=""){
        $temp=$text==""?$this->content:$text;
        preg_match_all("/{\&([a-zA-Z0-9_]*)=}(.*){\/\&\\1}/Us", $temp, $matches);
        $i=0;
        foreach($matches[0] as $old){
            $var=$matches[1][$i];
            $val=$matches[2][$i];
	    $val=$this->ifs($val);
	    $val=$this->vars($val);
            $val=$this->local_vars($val);
            $val=$this->symbionts($val);
            $val=$this->labels($val);
	    $this->intro_globals->push('sym');
            $this->intro_content.='$sym->'.$this->symbiont.'->'.$var.'=\''.$val.'\';';
            $new='';
            $temp=str_replace($old, $new, $temp);
            ++$i;
        }
        if($i!=0) $this->globals->push('sym');
        if($text==""){
            $this->content=$temp;
        }
        else{
            return $temp;
        }
    }
    //Add gloagls
    function add_globals(){
        if($this->globals->count()){
            $this->content="<? global \$".join(", \$", $this->globals->get())."; ?>".$this->content;
        }
	if($this->intro_globals->count()){
            $this->intro_content="global \$".join(", \$", $this->globals->get())."; ".$this->intro_content;
        }
    }
    //Include template
    function inc(){
        if(file_exists($this->template)){
            include($this->template);
        }
        else{
            $m=new message("Темлейт не существует.");
        }
    }
    //Get class value
    function get($key="*"){
        if($key=="*") return get_class_vars(get_class($this));
        else return $this->$key;
    }
    //Set class value
    function set($key, $val){
        $this->$key=$val;
    }
    /*
      @ GET/SET private properties
    */
    public function __get($var){
	return $this->$var;
    }
    public function __set($var, $val){
	$this->$var = $val;
    }
    static function run($text){
	global $sym, $kernel, $user;
	ob_start();
	eval('?>'.$text.'<?');
	return ob_get_clean();
    }
};
?>